package com.lnn.springBase.utils;

import lombok.extern.slf4j.Slf4j;
import ucar.ma2.Array;
import ucar.ma2.DataType;
import ucar.ma2.Index;
import ucar.ma2.IndexIterator;
import ucar.ma2.InvalidRangeException;
import ucar.nc2.Attribute;
import ucar.nc2.Dimension;
import ucar.nc2.NetcdfFileWriter;
import ucar.nc2.Variable;
import ucar.nc2.constants.AxisType;
import ucar.nc2.dataset.NetcdfDataset;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * NetCDF 文件读写工具类（支持多维度、多数据类型）
 * 使用构建者模式进行灵活配置。
 * 缩放因子和偏移量支持：
 *   存储值 = (原始值-add_offset)/scale_factor
 *   原始值 = 存储值*scale_factor+add_offset
 */
@Slf4j
public class NcFileUtils {

    private final List<NcDimension> dimensions = new ArrayList<>();
    private final List<NcVariable> variables = new ArrayList<>();
    private final Map<String, String> globalAttributes = new HashMap<>();

    private final static String  SCALE_FACTOR="scale_factor";
    private final static String  ADD_OFFEET="add_offset";//缩放因子


    // 新增静态时间格式配置
    private static DateTimeFormatter defaultTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

    // 新增时间格式配置方法
    public static void setDefaultTimeFormatter(DateTimeFormatter formatter) {
        defaultTimeFormatter = formatter;
    }

    private NcFileUtils() {}

    /**
     * 创建工具类实例
     */
    public static NcFileUtils create() {
        return new NcFileUtils();
    }

    /**
     * 添加时间维度（自动生成时间坐标）
     * @param name 维度名称
     * @param startTime 起始时间
     * @param timeUnit 时间单位（小时/天等）
     * @param timeSteps 时间步长数量
     */
    public NcFileUtils withTimeDimension(String name, LocalDateTime startTime,
                                         ChronoUnit timeUnit, int timeSteps,
                                         Consumer<NcDimension>... configs) {  // 新增配置参数
        NcDimension timeDim = new NcDimension(name, timeSteps, DataType.DOUBLE, AxisType.Time)
                .withTimeUnits(startTime, timeUnit);
        for (Consumer<NcDimension> config : configs) {
            config.accept(timeDim);
        }
        dimensions.add(timeDim);
        return this;
    }

    /**
     * 添加固定步长维度(经纬度等)
     * @param name 维度名称
     * @param length 长度
     * @param axisType 轴类型
     * @param start 起始值
     * @param step 步长
     * @return
     */
    public NcFileUtils withCoordinatesDimension(String name, int length, DataType dataType,
                                                AxisType axisType, float start, float step,
                                                Consumer<NcDimension>... configs) {  // 新增配置参数
        NcDimension dim = new NcDimension(name, length, dataType, axisType)
                .withCoordinateParams(start, step);
        for (Consumer<NcDimension> config : configs) {
            config.accept(dim);
        }
        dimensions.add(dim);
        return this;
    }


    /**
     * 添加自定义维度
     * @param name 维度名称
     * @param dataType 数据类型
     * @param axisType 轴类型
     * @param array 值
     */
    // 修改方法名并添加自动长度获取
    public NcFileUtils winthDimension(String name, DataType dataType, AxisType axisType, Object array,
                                      Consumer<NcDimension>... configs) {
        // 新增数组长度自动获取
        if (array == null) {
            throw new IllegalArgumentException("array参数不能为null");
        }
        int arrayLength = java.lang.reflect.Array.getLength(array);
        NcDimension dim = new NcDimension(name, arrayLength, dataType, axisType)
                .withArray(array);
        for (Consumer<NcDimension> config : configs) {
            config.accept(dim);
        }
        dimensions.add(dim);
        return this;
    }

    /**
     * 添加数据变量
     * @param name 变量名称
     * @param dataType 数据类型
     * @param dimensions 依赖的维度名称（按顺序）
     * @param configs 属性设置
     */
    public NcFileUtils withVariable(String name, DataType dataType, List<String> dimensions,Object array,
                                    Consumer<NcVariable>... configs) {  // 新增配置参数
        if (dimensions.size() == 0) {
            throw new IllegalArgumentException(name +" 至少需要一个维度");
        }
        // 基本类型校验
        if (array == null) {
            throw new IllegalArgumentException("array参数不能为null");
        }
        if (!array.getClass().isArray()) {
            throw new IllegalArgumentException("array参数必须是一个数组类型");
        }
        // 新增维度数量校验
        int arrayDimensions = getArrayDimensionCount(array);
        if (arrayDimensions != dimensions.size()) {
            throw new IllegalArgumentException(name + " 变量需要 " + dimensions.size()
                    + " 维数组，但传入的是 " + arrayDimensions + " 维数组");
        }
        NcVariable var = new NcVariable(name, dataType, dimensions,array);
        for (Consumer<NcVariable> config : configs) {
            config.accept(var);
        }
        variables.add(var);
        return this;
    }

    /**
     * 添加全局属性
     * @param key 属性键
     * @param value 属性值
     */
    public NcFileUtils withGlobalAttribute(String key, String value) {
        globalAttributes.put(key, value);
        return this;
    }

    /**
     * 写入NC文件
     * @param filename 输出文件名
     */
    public void write(String filename) throws IOException {
        NetcdfFileWriter writer = null; // 在外部声明变量
        try {
            writer = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf3, filename);
            final NetcdfFileWriter finalWriter = writer;
            // 维度与变量初始化
            Map<String, Dimension> ncDims = new HashMap<>();
            Map<String, Variable> coordVars = new HashMap<>();

            // 创建维度及坐标变量
            for (NcDimension dim : dimensions) {
                Dimension ncDim = writer.addDimension(null, dim.name, dim.length);
                ncDims.put(dim.name, ncDim);

                Variable coordVar = writer.addVariable(null, dim.name, dim.dataType, dim.name);
                dim.attributes.forEach((k, v) ->{
                    finalWriter.addVariableAttribute(coordVar, new Attribute(k, v));
                });
                coordVars.put(dim.name, coordVar);
            }

            // 创建数据变量
            Map<String, Variable> dataVars = new HashMap<>();
            for (NcVariable var : variables) {
                List<Dimension> varDims = var.dimensionNames.stream()
                        .map(ncDims::get).collect(Collectors.toList());

                // 修复点：使用维度名称数组而不是字符串拼接
                Variable ncVar = writer.addVariable(null, var.name, var.dataType,varDims);
                var.attributes.forEach((k, v) ->
                        finalWriter.addVariableAttribute(ncVar, new Attribute(k, v)));
                dataVars.put(var.name, ncVar);
            }

            // 添加全局属性
            globalAttributes.forEach((k, v) ->
                    finalWriter.addGroupAttribute(null, new Attribute(k, v)));

            // 创建文件结构
            writer.create();

            // 写入坐标数据
            for (NcDimension dim : dimensions) {
                writer.write(coordVars.get(dim.name), dim.createCoordinateArray());
            }

            // 写入变量数据
            for (NcVariable var : variables) {
                Object inputData = var.getArray();
                if(inputData==null){
                    log.error("该变量{} 缺少值", var.name);
                    continue;
                }
                int[] shape = var.dimensionNames.stream()
                        .mapToInt(d -> ncDims.get(d).getLength())
                        .toArray();
                Array arr = convertData(var.dataType, inputData, shape);
                // 新增缩放偏移处理
                if (var.attributes.containsKey(SCALE_FACTOR) || var.attributes.containsKey(ADD_OFFEET)) {
                    double scale = Double.parseDouble(var.attributes.getOrDefault(SCALE_FACTOR, "1.0"));
                    double offset = Double.parseDouble(var.attributes.getOrDefault(ADD_OFFEET, "0.0"));
                    arr = applyScaleOffset(arr, scale, offset, var.dataType);
                }
                writer.write(dataVars.get(var.name), arr);
            }
        } catch (InvalidRangeException e) {
            throw new RuntimeException(e);
        }finally {
            if (writer != null) { // 添加空指针检查
                writer.close();
            }
        }
    }

    public static Map<String, Array> read(String filePath, String... variables) throws IOException {
        Map<String, Array> result = new HashMap<>();
        try (NetcdfDataset ds = NetcdfDataset.openDataset(filePath)) {
            for (String varName : variables) {
                Variable var = ds.findVariable(varName);
                if (var != null) {
                    Array data = var.read();
                    // 新增时间类型处理
                    Attribute unitsAttr = var.findAttribute("units");
                    if (unitsAttr != null && unitsAttr.isString()) {
                        String units = unitsAttr.getStringValue();
                        if (units.contains(" since ")) {
                            try {
                                String[] parts = units.split(" since ");
                                ChronoUnit chronoUnit = parseChronoUnit(parts[0].trim());
                                LocalDateTime baseTime = LocalDateTime.parse(parts[1].trim(), defaultTimeFormatter );
                                // 转换时间坐标
                                String[] timeStrings = new String[(int) data.getSize()];
                                Index index = data.getIndex();
                                for (int i = 0; i < data.getSize(); i++) {
                                    double timeValue = data.getDouble(index.set(i));
                                    LocalDateTime dt = baseTime.plus((long) timeValue, chronoUnit);
                                    timeStrings[i] = dt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
                                }
                                // 替换为字符串类型的Array
                                data = Array.factory(DataType.STRING, data.getShape(), timeStrings);
                            } catch (Exception e) {
                                System.err.println("处理时间变量 " + varName + " 时出错: " + e.getMessage());
                            }
                        }
                    }
                    result.put(varName, data);
                }
            }
        }
        return result;
    }

    // 新增解析时间单位的方法
    private static ChronoUnit parseChronoUnit(String unit) {
        switch (unit.toLowerCase()) {
            case "hours": return ChronoUnit.HOURS;
            case "days": return ChronoUnit.DAYS;
            case "minutes": return ChronoUnit.MINUTES;
            case "seconds": return ChronoUnit.SECONDS;
            default: throw new IllegalArgumentException("不支持的时间单位: " + unit);
        }
    }

    /**
     * 读取NC文件并返回Java多维数组（新增方法）
     * @param filePath 文件名
     * @param variables 需要读取的变量名
     * @return 变量名 -> Java多维数组的映射
     */
    public static Map<String, Object> readAsJavaArrays(String filePath, String... variables) throws IOException {
        File file=new File(filePath);
        if(!file.exists()){
            log.error("文件不存在{}",filePath);
            throw new FileNotFoundException(filePath);
        }
        Map<String, Object> result = new HashMap<>();
        Map<String, Array> read = read(filePath, variables);
        for(String variable:read.keySet()){
            Array array = read.get(variable);
            result.put(variable,convertToJavaArray(array));
        }
        return result;
    }

    /**
     * 将NetCDF Array转换为Java多维数组（新增方法）
     */
    private static Object convertToJavaArray(Array array) {
        DataType dataType = array.getDataType();
        int[] shape = array.getShape();
        if (dataType == DataType.FLOAT) {
            switch (shape.length) {
                case 1: return convert1D(array, float[].class);
                case 2: return convert2D(array, float[][].class);
                case 3: return convert3D(array, float[][][].class);
                default:
                    System.err.println("不支持的维度或数据类型: " + shape.length + "D " + dataType);
                    return null;
            }
        } else if (dataType == DataType.DOUBLE) {
            switch (shape.length) {
                case 1: return convert1D(array, double[].class);
                case 2: return convert2D(array, double[][].class);
                case 3: return convert3D(array, double[][][].class);
                default:
                    System.err.println("不支持的维度或数据类型: " + shape.length + "D " + dataType);
                    return null;
            }
        } else if (dataType == DataType.STRING) {
            switch (shape.length) {
                case 1: return convert1D(array, String[].class);
                case 2: return convert2D(array, String[][].class);
                case 3: return convert3D(array, String[][][].class);
                default:
                    System.err.println("不支持的维度或数据类型: " + shape.length + "D " + dataType);
                    return null;
            }
        } else if (dataType == DataType.INT) {
            switch (shape.length) {
                case 1: return convert1D(array, int[].class);
                case 2: return convert2D(array, int[][].class);
                case 3: return convert3D(array, int[][][].class);
                default:
                    System.err.println("不支持的维度或数据类型: " + shape.length + "D " + dataType);
                    return null;
            }
        }else{
            System.err.println("补充 " + dataType + " 类型处理 ");
        }
        // 其他数据类型处理类似...
        return array.getStorage();
    }

    // 一维数组转换（补充完整类型支持）
    private static <T> T convert1D(Array array, Class<T> type) {
        int length = array.getShape()[0];
        IndexIterator iter = array.getIndexIterator();

        if (type == float[].class) {
            float[] result = new float[length];
            for (int i = 0; i < length; i++) {
                result[i] = iter.getFloatNext();
            }
            return type.cast(result);
        } else if (type == double[].class) {
            double[] result = new double[length];
            for (int i = 0; i < length; i++) {
                result[i] = iter.getDoubleNext();
            }
            return type.cast(result);
        } else if (type == int[].class) {
            int[] result = new int[length];
            for (int i = 0; i < length; i++) {
                result[i] = iter.getIntNext();
            }
            return type.cast(result);
        } else if (type == String[].class) {
            String[] result = new String[length];
            for (int i = 0; i < length; i++) {
                result[i] = iter.getObjectNext().toString();
            }
            return type.cast(result);
        }
        return null;
    }

    // 二维数组转换（补充完整类型支持）
    private static <T> T convert2D(Array array, Class<T> type) {
        int dim1 = array.getShape()[0];
        int dim2 = array.getShape()[1];
        IndexIterator iter = array.getIndexIterator();

        if (type == float[][].class) {
            float[][] result = new float[dim1][dim2];
            for (int i = 0; i < dim1; i++) {
                for (int j = 0; j < dim2; j++) {
                    result[i][j] = iter.getFloatNext();
                }
            }
            return type.cast(result);
        } else if (type == double[][].class) {
            double[][] result = new double[dim1][dim2];
            for (int i = 0; i < dim1; i++) {
                for (int j = 0; j < dim2; j++) {
                    result[i][j] = iter.getDoubleNext();
                }
            }
            return type.cast(result);
        } else if (type == int[][].class) {
            int[][] result = new int[dim1][dim2];
            for (int i = 0; i < dim1; i++) {
                for (int j = 0; j < dim2; j++) {
                    result[i][j] = iter.getIntNext();
                }
            }
            return type.cast(result);
        } else if (type == String[][].class) {
            String[][] result = new String[dim1][dim2];
            for (int i = 0; i < dim1; i++) {
                for (int j = 0; j < dim2; j++) {
                    result[i][j] = iter.getObjectNext().toString();
                }
            }
            return type.cast(result);
        }
        return null;
    }

    // 三维数组转换（补充完整类型支持）
    private static <T> T convert3D(Array array, Class<T> type) {
        int[] shape = array.getShape();
        Index iterator = array.getIndex();

        if (type == float[][][].class) {
            float[][][] result = new float[shape[0]][shape[1]][shape[2]];
            for (int i = 0; i < shape[0]; i++) {
                for (int j = 0; j < shape[1]; j++) {
                    for (int k = 0; k < shape[2]; k++) {
                        result[i][j][k] = array.getFloat(iterator.set(i, j, k));
                    }
                }
            }
            return type.cast(result);
        } else if (type == double[][][].class) {
            double[][][] result = new double[shape[0]][shape[1]][shape[2]];
            for (int i = 0; i < shape[0]; i++) {
                for (int j = 0; j < shape[1]; j++) {
                    for (int k = 0; k < shape[2]; k++) {
                        result[i][j][k] = array.getDouble(iterator.set(i, j, k));
                    }
                }
            }
            return type.cast(result);
        } else if (type == int[][][].class) {
            int[][][] result = new int[shape[0]][shape[1]][shape[2]];
            for (int i = 0; i < shape[0]; i++) {
                for (int j = 0; j < shape[1]; j++) {
                    for (int k = 0; k < shape[2]; k++) {
                        result[i][j][k] = array.getInt(iterator.set(i, j, k));
                    }
                }
            }
            return type.cast(result);
        } else if (type == String[][][].class) {
            String[][][] result = new String[shape[0]][shape[1]][shape[2]];
            for (int i = 0; i < shape[0]; i++) {
                for (int j = 0; j < shape[1]; j++) {
                    for (int k = 0; k < shape[2]; k++) {
                        result[i][j][k] = array.getObject(iterator.set(i, j, k)).toString();
                    }
                }
            }
            return type.cast(result);
        }
        return null;
    }

    private static Array convertToOriginal(Array storedData, double scale, double offset) {
        // 创建新数组（自动提升为浮点类型）
        int[] shape = storedData.getShape();
        Array result = Array.factory(DataType.DOUBLE, shape);

        IndexIterator src = storedData.getIndexIterator();
        IndexIterator dest = result.getIndexIterator();

        while (src.hasNext()) {
            double storedValue = src.getDoubleNext();
            double originalValue = storedValue * scale + offset;
            dest.setDoubleNext(originalValue);
        }

        return result;
    }

    // 修改原有读取方法（保持兼容性）
    @Deprecated
    private static Map<String, Array> readRaw(String filename, String... variables) throws IOException {
        Map<String, Array> result = new HashMap<>();
        try (NetcdfDataset ds = NetcdfDataset.openDataset(filename)) {
            for (String varName : variables) {
                Variable var = ds.findVariable(varName);
                if (var != null) {
                    result.put(varName, var.read());
                }
            }
        }
        return result;
    }

    private static Array applyScaleOffset(Array data, double scale, double offset, DataType targetType) {
        // 获取原始数组信息
        int[] shape = data.getShape();
        Array scaledArray = Array.factory(targetType, shape);

        // 遍历所有元素进行缩放和偏移计算
        IndexIterator srcIter = data.getIndexIterator();
        IndexIterator destIter = scaledArray.getIndexIterator();

        while (srcIter.hasNext()) {
            double value = srcIter.getDoubleNext();
            double scaledValue;
            // 新增NaN值判断
            if (Double.isNaN(value)) {
                if (targetType.isFloatingPoint()) {
                    scaledValue = Double.NaN;
                } else {
                    // 对于整型数据保持原处理方式
                    scaledValue = 0;
                }
            } else {
                scaledValue = (value - offset) / scale;
            }
            // 存储值 = (原始值 - offset) / scale
            // 根据目标数据类型处理
            switch (targetType) {
                case FLOAT:
                    destIter.setFloatNext(Float.isNaN((float) scaledValue) ?
                            Float.NaN : (float) scaledValue);
                    break;
                case DOUBLE:
                    destIter.setDoubleNext(Double.isNaN(scaledValue) ?
                            Double.NaN : scaledValue);
                    break;
                case INT:
                    destIter.setIntNext(Double.isNaN(scaledValue) ?
                            0 : (int) Math.round(scaledValue));  // 非浮点类型处理
                    break;
                case SHORT:
                    destIter.setShortNext((short) Math.round(scaledValue));
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported data type: " + targetType);
            }
        }
        return scaledArray;
    }

    /**
     * 维度配置类
     */
    public static class NcDimension {
        final String name;
        final int length;
        final DataType dataType;
        final AxisType axisType;
        final Map<String, String> attributes = new HashMap<>();
        LocalDateTime timeStart;
        ChronoUnit timeUnit;

        private Float coordinateStart;
        private Float coordinateStep;
        private Object dimensionArray;


        NcDimension(String name, int length, DataType dataType, AxisType axisType) {
            this.name = name;
            this.length = length;
            this.dataType = dataType;
            this.axisType = axisType;
            if(AxisType.Lat.equals(axisType)){
                this.attributes.put("units", "degrees_north");
            }
            if (AxisType.Lon.equals(axisType)) {
                this.attributes.put("units", "degrees_east");
            }
        }

        /**
         * 配置同样步长的参数
         * @param start 起始值
         * @param step 步长
         */
        NcDimension withCoordinateParams(float start, float step) {
            this.coordinateStart = start;
            this.coordinateStep = step;
            return this;
        }

        /**
         * 配置自定义数组
         * @param array 定义值
         */
        NcDimension withArray(Object  array) {
            validateArrayType(array);  // 添加类型验证
            this.dimensionArray = array;
            return this;
        }

        /**
         * 配置时间维度单位
         * @param start 起始时间
         * @param unit 时间单位
         */
        NcDimension withTimeUnits(LocalDateTime start, ChronoUnit unit) {
            this.timeStart = start;
            this.timeUnit = unit;
            this.attributes.put("units",
                    unit.toString().toLowerCase() + " since " +
                            start.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
            return this;
        }

        /**
         * 添加边界属性配置
         * @param boundsVarName 边界变量名称
         */
        public NcDimension withBounds(String boundsVarName) {
            this.attributes.put("bounds", boundsVarName);
            return this;
        }

        /**
         * 组合设置缩放因子和偏移值
         * @param scaleFactor 缩放因子
         * @param addOffset 偏移值
         */

        public NcDimension withScaleAndOffset(double scaleFactor, double addOffset) {
            attributes.put(SCALE_FACTOR, String.valueOf(scaleFactor));
            attributes.put(ADD_OFFEET, String.valueOf(addOffset));
            return this;
        }

        // 通用属性设置方法
        public NcDimension withAttribute(String key, Object value) {
            attributes.put(key, value.toString());
            return this;
        }

        /**
         * 生成坐标数组
         */
        Array createCoordinateArray() {
            // 优先使用用户传入的自定义数组
            // 处理自定义数组（新增类型转换逻辑）
            if (dimensionArray != null) {
                switch (dataType) {
                    case FLOAT:
                        return Array.factory(DataType.FLOAT, new int[]{length}, (float[]) dimensionArray);
                    case DOUBLE:
                        return Array.factory(DataType.DOUBLE, new int[]{length}, (double[]) dimensionArray);
                    case INT:
                        return Array.factory(DataType.INT, new int[]{length}, (int[]) dimensionArray);
                    case LONG:
                        return Array.factory(DataType.LONG, new int[]{length}, (long[]) dimensionArray);
                    default:
                        throw new IllegalArgumentException("Unsupported array type: " + dataType);
                }
            }
            // 处理时间维度（保持原有逻辑）
            if (axisType == AxisType.Time) {
                double[] times = new double[length];
                for (int i = 0; i < length; i++) {
                    times[i] = timeUnit.between(timeStart, timeStart.plus(i, timeUnit));
                }
                return Array.factory(DataType.DOUBLE, new int[]{length}, times);
            }else{

            }
            // 处理常规坐标生成（当没有自定义数组时）
            if (coordinateStart != null && coordinateStep != null) {
                float[] values = new float[length];
                for (int i = 0; i < length; i++) {
                    values[i] = coordinateStart + i * coordinateStep;
                }
                return Array.factory(DataType.FLOAT, new int[]{length}, values);
            }
            log.error("Dimension {} 无法 初始化,请设置相关属性", name);
            return null;
        }

        // 新增数组类型验证方法
        private void validateArrayType(Object array) {
            if (array == null) return;

            Class<?> componentType = array.getClass().getComponentType();
            if (componentType == null) {
                throw new IllegalArgumentException("必须提供数组类型");
            }

            // 允许包装类型数组并自动转换
            if (!isValidComponentType(componentType)) {
                throw new IllegalArgumentException("仅支持以下类型数组: float/double/int/long 及其包装类型");
            }

            // 新增自动类型转换逻辑
            convertWrapperArrayToPrimitive(array);
        }

        // 新增类型校验方法
        private boolean isValidComponentType(Class<?> componentType) {
            return componentType.isPrimitive() ||
                    componentType == Float.class ||
                    componentType == Double.class ||
                    componentType == Integer.class ||
                    componentType == Long.class ||
                    componentType == String.class;
        }

        // 新增包装类型数组转换逻辑
        private void convertWrapperArrayToPrimitive(Object array) {
            Class<?> componentType = array.getClass().getComponentType();

            if (componentType == Float.class) {
                Float[] wrapperArray = (Float[]) array;
                float[] primitiveArray = new float[wrapperArray.length];
                for (int i = 0; i < wrapperArray.length; i++) {
                    primitiveArray[i] = wrapperArray[i] != null ? wrapperArray[i] : Float.NaN;
                }
                this.dimensionArray = primitiveArray;
            } else if (componentType == Double.class) {
                Double[] wrapperArray = (Double[]) array;
                double[] primitiveArray = new double[wrapperArray.length];
                for (int i = 0; i < wrapperArray.length; i++) {
                    primitiveArray[i] = wrapperArray[i] != null ? wrapperArray[i] : Double.NaN;
                }
                this.dimensionArray = primitiveArray;
            } else if (componentType == Integer.class) {
                Integer[] wrapperArray = (Integer[]) array;
                int[] primitiveArray = new int[wrapperArray.length];
                for (int i = 0; i < wrapperArray.length; i++) {
                    primitiveArray[i] = wrapperArray[i] != null ? wrapperArray[i] : 0;
                }
                this.dimensionArray = primitiveArray;
            } else if (componentType == Long.class) {
                Long[] wrapperArray = (Long[]) array;
                long[] primitiveArray = new long[wrapperArray.length];
                for (int i = 0; i < wrapperArray.length; i++) {
                    primitiveArray[i] = wrapperArray[i] != null ? wrapperArray[i] : 0L;
                }
                this.dimensionArray = primitiveArray;
            }
        }
// ... existing code ...
    }

    /**
     * 变量配置类
     */
    public static class NcVariable {
        final String name;
        final DataType dataType;
        final Object array;
        final List<String> dimensionNames;
        final Map<String, String> attributes = new HashMap<>();

        NcVariable(String name, DataType dataType,List<String> dimensionNames, Object array) {
            this.name = name;
            this.dataType = dataType;
            this.dimensionNames = dimensionNames;
            this.array = array;
        }

        // 新增变量属性配置方法
        /**
         * 组合设置缩放因子和偏移值
         * @param scaleFactor 缩放因子
         * @param addOffset 偏移值
         */
        public NcVariable withScaleAndOffset(double scaleFactor, double addOffset) {
            attributes.put(SCALE_FACTOR, String.valueOf(scaleFactor));
            attributes.put(ADD_OFFEET, String.valueOf(addOffset));
            return this;
        }

        public NcVariable withAttribute(String key, Object value) {
            attributes.put(key, value.toString());
            return this;
        }

        Object getArray() {
            return array;
        }
    }

    /**
     * 数据类型转换器
     */
    private Array convertData(DataType targetType, Object data, int[] shape) {
        // 通用维度处理（支持1-5维数组）
        if (data != null && data.getClass().isArray()) {
            Class<?> componentType = data.getClass().getComponentType();
            if (componentType.isPrimitive() || componentType.isArray()) {
                return Array.factory(targetType, shape, flattenMultiDimensionalArray(data));
            }
        }
        return Array.factory(targetType, shape, data);
    }

    // 通用数组扁平化方法
    private static Object flattenMultiDimensionalArray(Object array) {
        List<Object> flatList = new ArrayList<>();
        flatten(array, flatList);

        // 根据元素类型创建对应基本类型数组（保留NaN）
        if (!flatList.isEmpty()) {
            Object sample = flatList.get(0);
            if (sample instanceof Float) {
                float[] result = new float[flatList.size()];
                for (int i = 0; i < result.length; i++) {
                    result[i] = (Float) flatList.get(i);
                    if (Float.isNaN(result[i])) result[i] = Float.NaN; // 显式保留NaN
                }
                return result;
            } else if (sample instanceof Double) {
                double[] result = new double[flatList.size()];
                for (int i = 0; i < result.length; i++) {
                    result[i] = (Double) flatList.get(i);
                    if (Double.isNaN(result[i])) result[i] = Double.NaN;// 自动保留Double.NaN
                }
                return result;
            } else if (sample instanceof Integer) {
                int[] result = new int[flatList.size()];
                for (int i = 0; i < result.length; i++) {
                    result[i] = (Integer) flatList.get(i);
                }
                return result;
            }
        }
        return flatList.toArray();
    }

    // 递归展开逻辑保持不变
    private static void flatten(Object array, List<Object> result) {
        if (array == null) return;

        if (array.getClass().isArray()) {
            int length = java.lang.reflect.Array.getLength(array);
            for (int i = 0; i < length; i++) {
                Object element = java.lang.reflect.Array.get(array, i);
                flatten(element, result);
            }
        } else {
            // 直接保留原始值（包括NaN）
            result.add(array);
        }
    }

    // 新增维度数量计算方法
    private static int getArrayDimensionCount(Object array) {
        int dimensions = 0;
        Class<?> clazz = array.getClass();
        while (clazz.isArray()) {
            dimensions++;
            clazz = clazz.getComponentType();
        }
        return dimensions;
    }
}
